#pragma once
#include "AsCoreGlobal.h"
#include <QJsonValue>
#include <QJsonObject>
#include <QVector>
#include <QJsonArray>

class AS_CORE_EXPORT AsJsonFile {
public:
	typedef QVector<QPair<QString, QJsonValue>> KVPairTab;

public:
	AsJsonFile();
	AsJsonFile(QString filename);

private:
	QJsonObject m_obj;
	QString		m_filename;

public:
	bool load(const QString& filename = QString());
	bool save(const QString& filename = QString());
	// 键值对表加载：存在于kvTab中的键被加载，不存在kvTab中的键被删除，不存在文件中的键被默认值添加
	bool load(const KVPairTab& kvTab, const QString& filename = QString());
	// 键值对表保存：kvTab的键值对加载到AsJsonFile中，并将其保存
	bool save(const KVPairTab& kvTab, const QString& filename = QString());
	void clear();
	bool addKey(const QString& key, const QJsonValue& value);
	bool delKey(const QString& key);
	bool containsKey(const QString& key) const;
	bool setValue(const QString& key, const QJsonValue& value);
	QJsonValue getValue(const QString& key) const;
	bool getValue(const QString& key, QString& value) const;
	bool getValue(const QString& key, int& value) const;
	bool getValue(const QString& key, qint64& value) const;
	bool getValue(const QString& key, float& value) const;
	bool getValue(const QString& key, double& value) const;
	bool getAll(QVector<QString>& keyArray, QVector<QJsonValue>& valueArray) const;
	bool getBool(const QString& key) const;
	int getInt(const QString& key) const;
	qint64 getInt64(const QString& key) const;
	double getDouble(const QString& key) const;
	QString getString(const QString& key) const;
	QJsonObject getRootObject();
	void setRootObject(const QJsonObject& js);

	//to get a user define value
	template<class T>
	bool getValue(const QString& key, T& value) {
		if (!m_obj.contains(key)|| !m_obj[key].isObject()) {
			return false;
		}
		value.fromJsonObject(m_obj[key].toObject());
		return true;
	}

	//to add a user define value
	template<class T>
	void setData(const QString& key, const T& value){
		m_obj[key] = value.toJsonObject();
	}

	//to get a user define array
	template<class T>
	bool getArray(const QString& key, QVector<T>& array) {
		if (!m_obj.contains(key)|| !m_obj[key].isArray()) {
			return false;
		}
		QJsonArray jsArray = m_obj[key].toArray();
		array.clear();
		for (const auto& js : jsArray) {
			T data;
			data.fromJsonObject(js.toObject());
			array << data;
		}
		return true;
	}

	//to add a user define array
	template<class T>
	void setArray(const QString& key, const QVector<T>& array) {
		QJsonArray jsArray;
		for (const auto& data : array) {
			jsArray << data.toJsonObject();
		}
		m_obj[key] =jsArray;
	}
};
